package com.ruoyi.framework.manager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 确保应用退出时能关闭后台线程
 *
 * @author ruoyi
 */
@Component
public class ShutdownManager
{
    private static final Logger logger = LoggerFactory.getLogger("sys-user");
    private final ThreadPoolExecutor threadPoolExecutor;

    public ShutdownManager(ThreadPoolExecutor threadPoolExecutor) {
        this.threadPoolExecutor = threadPoolExecutor;
    }

    @PreDestroy
    public void destroy()
    {

        try
        {
            if (!threadPoolExecutor.awaitTermination(30, TimeUnit.SECONDS))
            {
                threadPoolExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            logger.error("线程池关闭异常", e);
            throw new RuntimeException(e);
        }
        shutdownAsyncManager();
    }

    /**
     * 停止异步执行任务
     */
    private void shutdownAsyncManager()
    {
        try
        {
            logger.info("开始关闭线程池...");
            // 调用封装的关闭线程池方法
            shutdownThreadPool(threadPoolExecutor);
            // 处理 AsyncManager 关闭并捕获异常
            try {
                AsyncManager.me().shutdown();
            } catch (Exception e) {
                logger.error("AsyncManager 关闭异常", e);
            }
        }
        catch (Exception e)
        {
            logger.error(e.getMessage(), e);
        }
    }
    /**
     * 封装线程池关闭逻辑
     */
    private void shutdownThreadPool(ThreadPoolExecutor executor) {
        logger.info("关闭线程池...");
        executor.shutdown();
        try {
            if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
                logger.warn("线程池未在指定时间内关闭，尝试强制关闭");
                executor.shutdownNow();
                logger.warn("线程池已强制关闭");
            }
        } catch (InterruptedException e) {
            logger.error("线程池关闭时被中断", e);
            executor.shutdownNow();
        }
        logger.info("线程池已成功关闭");
    }
}
